home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
United Public Domain Gold 2
/
United Public Domain Gold 2.iso
/
utilities
/
pu300.dms
/
pu300.adf
/
Tutor.1
/
morse.s
< prev
next >
Wrap
Text File
|
1990-05-26
|
61KB
|
1,575 lines
** morse.s Version 1.1
** A program in assembly language to make morse code sending and
** random code generating routines. Started on April 30, 1097.
** By Peter V. Inskeep ars/ NO2D
** 6 Clearview Drive
** Long Valley, N. J., 07853
** CIS 72017,1211
** CIS E-Mail inquiries encouraged
** Created primarily as an exploration of assembly language programming
** on the Amiga. But it would be nice also if this adventure in morse
** code created enough enthusiasm to cause you to look into ham radio
** if you are not already a ham. Contact a ham (look for big antennas
** in the back yard), or call ARRL in Newington, Ct., for the name of
** a ham club near you.
* = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - *
*** Special thanks to Darrel Schneider, Author of SpriteClock, on ***
*** Fred Fish Disk # 43. That program gave me the clues on how ***
*** to open the timer.device and get it to _LVODoIO. The source ***
*** to Sclock has many very interesting assembly language ideas. ***
** INCLUDE files normally used in compiling an assembly language
** program are not needed if the equates listed below are used. There
** are obscure switches included to turn the equates on or off as
** you desire. They are on now, so no INCLUDE directives are not needed.
** The equates are used to speed assembly, as running the assembler
** through many INCLUDE files takes a long time.
; INCLUDE 'exec/types.i' ;these will conflict with the equates
; INCLUDE 'exec/io.i' ;so are turned off by the [ ; ].
; INCLUDE 'intuition/intuition.i'
; INCLUDE 'outfile.equ' ;use this only if you have outfile.equ
; file built and installed in the include directory on assembly disk
** Some switches
useoutfile equ 1 ;equ 1 if you are not using outfile.equ
useincludes equ 1 ;equ 1 if you are not using any includes at all
XREF _LVOGetMsg
XREF _LVOReplyMsg
XREF _LVOAddPort
XREF _LVORemPort
XREF _LVOSetMenuStrip
XREF _LVOClearMenuStrip
XREF _LVOPrintIText
XREF _LVODrawBorder
XREF _LVOOpenWindow
XREF _LVOCloseWindow
XREF _LVOAddDevice
XREF _LVOOpenDevice
XREF _LVOCloseDevice
XREF _LVORemDevice
XREF _LVOOpenLibrary
XREF _LVOCloseLibrary
XREF _LVODoIO
XREF _LVOSendIO
XREF _LVOWait
XREF _LVOAddGadget
XREF _LVOAllocMem
XREF _LVOFreeMem
XREF _LVOAllocSignal
XREF _LVOFreeSignal
XREF _LVOFindTask
** Outfile.equ equates - the following items are defined in a file called
** outfile.equ. This file is created by assembling all of the desired
** INCLUDE files with the -e outfile.equ switch turned on. The -e
** directive is not well documented in the literature, but is explained
** in one of the back issues of Transactor. I can not remember which.
IFEQ 1-useoutfile ;IF NOT EQUAL ZERO THEN THESE ARE NOT USED
AbsExecBase EQU $04
NT_MSGPORT EQU $04
NT_MESSAGE EQU $05
LN_TYPE EQU $08
LN_PRI EQU $09
LN_NAME EQU $0A
LN_SIZE EQU $0E
MEMF_PUBLIC EQU $01
MEMF_CHIP EQU $02
MEMF_FAST EQU $04
MEMF_CLEAR EQU $10000
ENDC
*** DMA CHIP ADDRESSES - FROM THE HARDWARE MANUAL
*** NOT CURRENTLY IN INCLUDE OR OUTFILE.EQU SO ALWAYS USE
Chipadr equ $dff000 ;base address of chip
DMAconw equ Chipadr+$96 ;DMA control write register
Aud0Lc equ Chipadr+$a0 ;Channel 0 waveform sample location
Aud0Len equ Chipadr+$a4 ;Channel 0 waveform sample length
Aud0per equ Chipadr+$a6 ;channel 0 period
Aud0vol equ Chipadr+$a8 ;channel 0 volume
Aud1Lc equ Chipadr+$b0 ;Channel 1 waveform sample location
Aud1Len equ Chipadr+$b4 ;Channel 1 waveform sample length
Aud1per equ Chipadr+$b6 ;channel 1 period
Aud1vol equ Chipadr+$b8 ;channel 1 volume
Setclr equ $08000 ;DMA SEETCLR bit
OffDMA equ 0 ;Disable DMA
Aud0en equ $01 ;enable/disable Channel 0
Aud1en equ $02 ;Enable/disable Channel 1
DMAen equ $0200 ;Enable DMA
timelsb equ $bfe801 ;timer a Least sig byte - read last
timemid equ $bfe901 ;timer a middle byte
timemsb equ $bfea01 ;timer a MSB - read stops clock til LSB read
timecrb equ $bfef01 ;timer a control register bit 7=0 is write
** INCLUDE EQUATES FROM EITHER INCLUDE OR OUTFILE.EQU
** Do not use these [set not =] if using include or outfile.equ
IFEQ 1-useincludes ;IF NOT ZERO THEN WILL NOT BE EQUATED
wd_RPort equ $32
wd_FirstGadget equ $3e
wd_Size equ $7c
ig_ImageData equ $0a
ig_SIZEOF EQU $14
wd_UserPort equ $56
nw_FirstGadget equ $12
im_Class equ $14
im_Code equ $18
im_MouseX equ $20
im_MouseY equ $22
im_Seconds equ $24
im_Micros equ $28
MP_FLAGS EQU $0E
MP_SIGBIT equ $0f
MP_SIGTASK EQU $10
MP_MSGLIST EQU $14
MP_SIZE EQU $22
MENUENABLED equ $01
MIDRAWN equ $100
ITEMTEXT equ $02
ITEMENABLED equ $10
WBENCHSCREEN equ $01
HIGHCOMP equ $40
WINDOWSIZING equ $01
WINDOWDRAG equ $02
WINDOWDEPTH equ $04
WINDOWCLOSE equ $08
SMART_REFRESH equ $00
ACTIVATE equ $1000
GIMMEZEROZERO equ $400
VANILLAKEY EQU $00200000 ;SEE OPENWINDOW IN INTUITION REF MANL
FOLLOWMOUSE EQU $08
CHECKIT EQU $01 ;
COMMSEQ EQU $04
MENUTOGGLE EQU $08
TR_GETSYSTIME EQU $0A ;used with the timer.device
TR_SETSYSTIME EQU $0B
TR_ADDREQUEST EQU $09
CMD_READ EQU $02
CMD_WRITE EQU $03
CMD_NONSTD EQU $09
MN_REPLYPORT equ $0e
MN_SIZE EQU $14
IO_DEVICE EQU $14 ;THE IO_STDREQ STRUCTURE IS BEST DESCRIBED IN THE
IO_UNIT EQU $18 ;ROM KERNAL SERIAL.DEVICE ON PG D40.
IO_COMMAND EQU $1C
IO_FLAGS EQU $1E
IO_ERROR EQU $1F
IO_ACTUAL EQU $20
IO_LENGTH EQU $24
IO_DATA EQU $28
IO_OFFSET EQU $2C
IOSTD_SIZE EQU $30
IO_SIZE EQU $20
IOTV_TIME EQU $20
TV_SIZE EQU $08
IOTV_SIZE EQU $28
TV_SECS EQU $00
TV_MICRO EQU $04
UNIT_MICROHZ EQU $00
UNIT_VBLANK EQU $01
pi_SIZEOF EQU $16
pi_Flags EQU $00
pi_HorizPot EQU $02
pi_VertPot EQU $04
pi_HorizBody EQU $06
pi_VertBody EQU $08
pi_HPotRes EQU $0e
pi_VPotRes EQU $10
AUTOKNOB EQU $01
FREEHORIZ EQU $02
FREEVERT EQU $04
KNOBHIT EQU $0100
KNOBHMIN EQU 6
KNOBVMIN EQU 4
gg_NextGadget equ $00
gg_LeftEdge equ $04
gg_TopEdge equ $06
gg_Width equ $08
gg_Height equ $0a
gg_Flags equ $0c
gg_Activation equ $0e
gg_GadgetType equ $10
gg_GadgetRender equ $12
gg_SelectRender equ $16
gg_GadgetText equ $1a
gg_MutualExclude equ $1e
gg_SpecialInfo equ $22
gg_GadgetID equ $26
gg_UserData equ $28
gg_SIZEOF equ $1c
RELVERIFY EQU $01
RIGHTBORDER EQU $10
BOTTOMBORDER EQU $80
PROPGADGET EQU $03
GZZGADGET EQU $2000
CLOSEWINDOW EQU $0200
GADGETUP EQU $40
MENUPICK EQU $0100
GRELRIGHT EQU $10
GRELHEIGHT EQU $40
GRELWIDTH EQU $20
GRELBOTTOM EQU $08
GADGIMAGE EQU $04
GADGHIMAGE EQU $02
GADGHCOMP EQU $00
RP_JAM1 EQU $00
RP_JAM2 EQU $01
ENDC
*** Program equates not defined in Include or Outfile.equ
million equ 1000000
Priority equ $00
maxspeed equ $a00
linelen equ 54 ;set to typed line length
Count equ $ffff ;counter for delay timer
bufferlen equ 400 ;keyboard buffer length not more than #keybuf
gwide equ 22 ;how wide the gadget box is ( -GRELWIDTH)
ghigh equ -40 ;how high the gadget box is (-GRELHEIGHT
gleft equ -22 ;where the left edge of the box is (-GRELRIGHT)
gtop equ 15 ; -40 ;where the top of the box is (-GRELBOTTOM)
g1wide equ 300
g1high equ 12 ; -15
g1left equ 100
g1top equ -12
** The following macro added by P.V.Inskeep, on 30,May,1987, to
** accomodate the need to copy a structure size into a program
** being written, and to consume the correct number of BYTES!
** It is also initialized to zero with the dcb.b command
IFND MYSTRUCT
MYSTRUCT MACRO ;mystructname,mystructendaddr
\1 dcb.b \2,0
ENDM
ENDC
start:
*** Open the Intuition Library ***
movea.l #IntuitionName,a1 ;ask for intuition.library
clr.l d0 ;accept any version 0 or greater
movea.l AbsExecBase,a6 ;the one fixed location in Amiga
jsr _LVOOpenLibrary(a6) ;assembly language programming
move.l d0,IntuitionLibrary ;store the pointer here
beq Abort ;if zero then open failed so we go away
** Open graphics - need for clear screen
movea.l #GraphicsName,a1 ;ask for the graphics.library
clr.l d0 ;any version
movea.l AbsExecBase,a6
jsr _LVOOpenLibrary(a6)
move.l d0,GraphicsLibrary ;store the pointer here
beq Abort
*** Get some Chip Memory for Images, etc.
getmem: ;for image and audio
move.l #imagebytes,d0 ;establish chip memory space for the
move.l #(MEMF_CHIP!MEMF_PUBLIC),d1 ;proportional gadgets and
movea.l AbsExecBase,a6 ;the audio wave sample
jsr _LVOAllocMem(a6)
tst.l d0 ;a ptr to the memoryblock or 0 if error
beq close2_image
move.l d0,memblock ;ptr to reserved memory block
move.l d0,a0 ;ptr to reserved mem block
clr.l d0 ;set up dbra register
move.l #imagebytes,d0 ;#sizepubmem,d0 ;how many iterations
sub.l #1,d0 ;goes to minus 1
lea.l theimage,a1 ;ptr to beginning of initial data
1$ move.b (a1)+,(a0)+ ;move data from begin to memblock
dbra d0,1$ ;loop until all copied
;image2 - pitch - transformation
move.l #pitchbytes,d0
move.l #(MEMF_CHIP!MEMF_PUBLIC),d1
movea.l AbsExecBase,a6
jsr _LVOAllocMem(a6)
tst.l d0 ;a ptr to the memoryblock or 0 if error
beq close3_pitch
move.l d0,pitchblock ;ptr to reserved memory block
move.l d0,a0 ;ptr to reserved mem block
clr.l d0 ;set up dbra register
move.l #pitchbytes,d0 ;how many iterations
sub.l #1,d0 ;goes to minus 1
lea.l pitchimage,a1 ;ptr to beginning of initial data
3$ move.b (a1)+,(a0)+ ;move data from begin to memblock
dbra d0,3$ ;loop until all copied
;now the audio block moves to chip memory
move.l #sizeaudio,d0
move.l #(MEMF_CHIP!MEMF_PUBLIC),d1
movea.l AbsExecBase,a6
jsr _LVOAllocMem(a6)
tst.l d0 ;a ptr to the memoryblock or 0 if error
beq close4_audio
move.l d0,audioblock ;ptr to reserved memory block
move.l d0,a0 ;ptr to reserved mem block
clr.l d0 ;set up dbra register
move.l #sizeaudio,d0 ;how many iterations
sub.l #1,d0 ;goes to minus 1
lea.l Wavesample,a1 ;ptr to beginning of initial data
2$ move.b (a1)+,(a0)+ ;move data from begin to memblock
dbra d0,2$ ;loop until all copied
*** Now initialize and open window and set pointers ***
jsr inits ;set up some chip mem pointers
jsr initializations ;set lots of pointers and buckets
********** create timer port **********
init_timerport:
;get a signal bit
moveq.l #-1,d0
jsr _LVOAllocSignal(a6)
move.l d0,MP_Signalbit ;d2
bmi close5_sigbit ; if -1 AllocSignal failed so abort
; alloc port structure
moveq.l #MP_SIZE,d0 ;set aside this many bytes for message port
move.l #(MEMF_CLEAR!MEMF_PUBLIC),d1 ;fill it with zeros
movea.l AbsExecBase,a6
jsr _LVOAllocMem(a6) ;needs d0 and d1, if successful returns
move.l d0,timerportptr ;ptr to the memory set aside
beq close6_MP ;failed if zero
; fill port fields
movea.l timerportptr,a2 ;ptr to our MP_ structure
move.b #NT_MSGPORT,LN_TYPE(a2) ;Exec book pg A-30
move.b #Priority,LN_PRI(a2) ;Priority = priority level 0
lea.l TimerPortName,a1 ;name is "timer"
move.l a1,LN_NAME(a2) ; LN_NAME gets TimerPortName "timer"
move.l MP_Signalbit,d2 ;bring back the signal bit. This puts the
move.w d2,MP_FLAGS(a2) ;signal bit in the lower 16 bits of d2,
; and writes them to the BYTES MP_FLAGS AND MP_SIGBIT
; Now find a task to put in the MP_SIGTASK field of the structure
moveq.l #0,d0 ;zero in a1
movea.l d0,a1 ;an odd way to zero out a1
jsr _LVOFindTask(a6) ;needs task or zero in a1
movea.l timerportptr,a1 ;now switch ptr to a1
move.l d0,MP_SIGTASK(a1) ;task returned in d0, init sigtask
; add the port
movea.l timerportptr,a1 ;there is no failure code for this,but
jsr _LVOAddPort(a6) ;it must be removed before the message
; initialize timerequest structure ;port is closed
moveq.l #IOTV_SIZE,d0 ;Enough bytes for IO Timerequest Structure
move.l #(MEMF_CLEAR!MEMF_PUBLIC),d1
jsr _LVOAllocMem(a6)
tst.l d0
beq close7_remport ;remove the port above and close out
move.l d0,timeIOTVptr ;save the IOTV ptr
move.l d0,a0 ;now init our IOTV block. This next step puts the
;message bit in high byte of word and priority bit in low byte, and
;stores them in a0+8 and a0+9 respectively
move.w #((NT_MESSAGE<<8)+Priority),LN_TYPE(a0)
move.l timerportptr,MN_REPLYPORT(a0) ; into a0+$0e
; the following flags should be cleared, and were in the AllocMem call
; but if not: clr.w IO_FLAGS(timeIOTVptr) ; this also zeros IO_ERROR
move.w #TR_ADDREQUEST,IO_COMMAND(a0) ;this tells _LVODoIO what
;command we want it to do for us.
OpenDeviceLOOP:
lea.l timername,a0 ;name is "timer.device
movea.l timeIOTVptr,a1 ;ptr to IOTV structure
moveq.l #UNIT_MICROHZ,d0 ;use UNIT_MICROHZ or UNIT_VBLANK
moveq.l #0,d1
movea.l AbsExecBase,a6
jsr _LVOOpenDevice(a6) ;error if not successful
tst.l d0
bne close8_IOTV
bra IntroMessage
delay3secs movea.l timeIOTVptr,a1 ;load our fully initialized IOTV ptr
move.l #3,IO_SIZE+TV_SECS(a1) ;delay 3 seconds
move.l #10,IO_SIZE+TV_MICRO(a1) ;delay 10 microseconds
movea.l AbsExecBase,a6 ;needs IO block in a1, returns error in
jsr _LVODoIO(a6) ;d0 or zero if successful
rts
dotpause movem.l d0-d4/a0-a4,-(sp) ;save the registers
jsr conchar ;get a key
movea.l timeIOTVptr,a1 ;load our fully initialized IOTV ptr
move.l secs,IO_SIZE+TV_SECS(a1) ;for dot & space elements
move.l micros,IO_SIZE+TV_MICRO(a1)
movea.l AbsExecBase,a6 ;needs IO block in a1, returns error in
jsr _LVODoIO(a6) ;d0 or zero if successful
movem.l (sp)+,d0-d4/a0-a4
rts
dashpause movem.l d0-d4/a0-a4,-(sp) ;save the registers
jsr conchar ;get a key
movea.l timeIOTVptr,a1 ;load our fully initialized IOTV ptr
move.l dashsecs,IO_SIZE+TV_SECS(a1) ;just for dashes
move.l dashmicros,IO_SIZE+TV_MICRO(a1)
movea.l AbsExecBase,a6 ;needs IO block in a1, returns error in
jsr _LVODoIO(a6) ;d0 or zero if successful
movem.l (sp)+,d0-d4/a0-a4
rts
initializations: ; nothing works unless these are initialized before
; being used in the various routines.
move.l #1,randflag ;set random for keyboard input
move.l #0,codecntr ;zero out code counter
move.l #0,kbcntr ;zero out keyboard counter
move.l #keybuf,kbptr ;the current keyboard buffer position
move.l #keybuf,codeptr ;the current code char position
move.l #keybuf,d0
add.l #bufferlen,d0 ;get to end of keybuf
move.l d0,kbendptr ;the end of keybuf
move.l d0,consoleflag ;make these two flags any non-zero
move.l d0,timerflag ;value so close1 works properly
move.l #mymenu,menupoint ;initialize pointer to menu structure
move.l #menuitemone,firstmenuitem ;init 1st menuitem pointer
move.l #firstitemtext,itemonetext ;init 1st item intuitext struct
move.l #fititle,fitext ;init title in 1st menu item
move.l #menuitemtwo,menuitemone ;init the second menu item
move.l #seconditemtext,itemtwotext ;and its text
move.l #sititle,sitext
move.l #menuitem3,menuitemtwo ;init third menu item
move.l #thirditemtext,item3text ;and its text
move.l #tititle,titext
move.l #menuitem4,menuitem3
move.l #forthitemtext,item4text
move.l #fotitle,fotext
move.l #onelinelist,oneline1 ;init drawline border coordinates
move.l #onecharbuf,onecharptr ;for writing one char
move.l #5,ranword ;for random char generator spacing
lea buffer,a1 ;initialize the buffer
move.l a1,bufptr ;pointer
move.l #0,secs ;initialize the counters for dot and dash
move.l #32000,micros ;three to one ratio
move.l #0,dashsecs
move.l #112000,dashmicros
move.l #2,factor ;the speed factor menu adjuster
** Set the Menu Strip
movea.l MyWindow,a0 ;pointers to window and to menu structure
movea.l menupoint,a1 ;needed to call SetMenuStrip
movea.l IntuitionLibrary,a6
jsr _LVOSetMenuStrip(a6)
rts
IntroMessage:
jsr welcomssg ;see if the messages work
move.l #100,d0 ;this is a short pause routine to let
;the user read the intro message
jsr pause ;time to read the screen
jsr setmessage ;set up the message center
bra openconsole
***** We went to the openconsole routine *****
cnop 0,4
** set up the IORequest block structure here
MYSTRUCT myio,IOSTD_SIZE
cnop 0,4
** Open Console.Device
** Start by init the iodata field to a pointer to MyWindow
** The open console device fills in all the rest.
** for the specific commands. see Intuition manual pg 174
openconsole:
;initialize to call adddevice
move.l #myio,a0 ;the reserved block pointer is ioreqptr
move.l a0,ioreqptr ;set up a ioblock pointer
move.l MyWindow,d1 ;get the window pointer
move.l d1,IO_DATA(a0) ;put the window ptr in IO_DATA
move.l #wd_Size,IO_LENGTH(a0) ;poke size of a window structure
**open device
movea.l #consolename,a0 ;console.device any other not do anything
move.l #0,d0 ;unit number
movea.l ioreqptr,a1 ;IORequest block structure i built
move.l #0,d1 ;flags dont know what to put
movea.l AbsExecBase,a6
jsr _LVOOpenDevice(a6) ;returns 0 if success, error if not
move.l d0,consoleflag ;keeps track of successful console open
tst.l d0 ;zero is success, not zero is error number
beq success
bra cl9_timerdevice ;close timer console et all
success:
move.l #iobuffer,d4 ;load a zero term mssg to print
jsr conwrite ;a short success message
tst.l d0 ;zero is success
bne close10 ;everything opened, but it didn't work
bra passover ;pass over the morse gadget initializations
** put the message pointer in d4, with zero terminated
conwrite:
movea.l ioreqptr,a0 ;pointer to iorequestblock structure
move.l #-1,IO_LENGTH(A0) ;use -1 only if text null terminated.
; otherwise, load iolength with buffer text length
move.l d4,IO_DATA(A0)
move.w #CMD_WRITE,IO_COMMAND(a0) ;WORD LENGTH
movea.l a0,a1 ;iorequestblock structure
movea.l AbsExecBase,a6
jsr _LVOSendIO(a6) ;DoIO works but waits for write to finish
rts ;and is therefore slower
conread:
movea.l ioreqptr,a0
move.l #10,IO_LENGTH(a0) ;read a maximum of ten chars.
move.w #CMD_READ,IO_COMMAND(a0) ;set up the read command
move.l a0,a1
move.l bufptr,IO_DATA(a0) ;fill the buffer from dos
movea.l AbsExecBase,a6
jsr _LVOSendIO(a6) ;88888errorcheck
rts
** Write one char in kbptr to the screen
conwone:
movea.l ioreqptr,a1 ;pointer to iorequestblock structure
move.l #1,IO_LENGTH(a1) ;use 1 to write one character
move.l kbptr,IO_DATA(a1)
move.w #CMD_WRITE,IO_COMMAND(a1) ;WORD LENGTH
movea.l AbsExecBase,a6
jsr _LVOSendIO(a6)
rts
** Read one char fm keyboard (kbptr)
conrone:
movea.l ioreqptr,a1 ;get ioreqblock base pointer
move.l #1,IO_LENGTH(a1) ;read 1 char
move.w #CMD_READ,IO_COMMAND(a1) ;set the read command
move.l kbptr,IO_DATA(a1) ;pointer where to store char
movea.l AbsExecBase,a6 ;needs base ptr in a1
jsr _LVOSendIO(a6)
rts
** gets a char if there is one in keyboard, and writes it. This is called
conchar: ;during sounds of dots and dashes (dotpause-dashpause)
clr.l d4 ;sending a dot or dash
movea.l ioreqptr,a0
move.w 30(a0),d4 ;bit 6 of #30 in iorequest block will be
btst #14,d4 ;1 if a char is available in read, otherwise
beq 1$ ;it will be zero
jsr conrone
jsr conwone ;there was a char
jsr addkeyst ;increment keyboard buffer ptr
1$ rts
* Initialize the variables
inits:
lea image1,a0 ;gadget1 image structure ptr
movea.l memblock,a1 ;ptr to gadget knob image data
move.l a1,ig_ImageData(a0) ;initialize image1 data ptr
lea image2,a0
movea.l pitchblock,a1
move.l a1,ig_ImageData(a0) ;init image2 data ptr
jsr sound ;initialize the sound subroutine
*** Open our window now that the propgadgets have been initialized
movea.l #newwindow,a0
movea.l IntuitionLibrary,a6
jsr _LVOOpenWindow(a6)
move.l d0,MyWindow ;pointer to newly opened window
beq Abort ;the rastport pointer is located
movea.l MyWindow,a0 ;at an address which is offset from
movea.l wd_RPort(a0),a1 ;the window pointer by the value of
move.l a1,myrport ;wd_RPort, which is hex $32
rts
passover:
jsr setmessage ;init these so DoIO can have a port
jsr getmessage
jsr sound ;initialize the sound
clr.l d0
move.w #200,Aud0per ;make a two tone sound to start up
move.w #250,Aud1per ;second channel should be lower pitch?
jsr ChanneL0 ;make a noise
jsr sound ;reinit the sound
move.l #40,d0
jsr pause
jsr sndon
jsr delay3secs ;just to see if it works
move.l #timertest,d4
jsr conwrite
jsr sndoff
move.l #40,d0
jsr pause
jsr clear
movea.l #cqmssg,a5 ;addr of message to send
jsr sendmorse
move.l #endline,d4
jsr conwrite
move.l #testmsg,d4
jsr conwrite ;print instructions
tst.l d0
bne close1 ;if it fails
jsr zerokeybuf ;fill keybuf with zeros
jsr conrone ;read once to set to #14 bit
bra ponder3 ;to the main loop
sendmorse: ;expects pointer to 0 terminate string in a5
2$ clr.l d0
move.b (a5)+,d0 ;get 1st character from mssg
tst.b d0 ;if 0 then done
beq 1$
move.l a5,-(a7) ;save mssg ptr
move.l d0,-(a7) ;save letter
move.b d0,prtachar ;load buffer
move.l #prtachar,d4 ;prepare for conwrite
jsr conwrite ;write 0 terminated buffer
move.l (a7)+,d0 ;get character back
jsr sendone ;send it as morse code sounds
move.l (a7)+,a5 ;get mssg ptr back
bra 2$
1$ rts
zerokeybuf:
move.l #keybuf,a0 ;start of keyboard buffer
clr.l d1
move.l #bufferlen,d1 ;one less than buffer length
sub.l #1,d1
1$ move.b #0,(a0)+ ;zero fill
dbra d1,1$ ;decrement and branch
rts
** The main routine for the menuitem selection.
** The Message Reading SubRoutine **
ponder3:
jsr getmessage ;go see if there is a message to read
tst.l d0 ;returns zero if none
beq ponder5 ;return if no message
clr.l d0 ;myclass contains the idcmp message upon [ponder4]
move.l myclass,d0 ;return from getmessage
cmp.w #MENUPICK,d0 ;was a menu picked
beq whichmenu ;if so, then go find out which menu item
cmp.w #CLOSEWINDOW,d0 ;or was it the closewindow gadget?
beq close1 ;if so, go close everything out
cmp.w #GADGETUP,D0 ;or was the gadget hit to change speed
beq chgspeed ;change the delay loop values
ponder5: ;bra keytest ;no message
jsr conchar ;is there a char at keyboard
jsr codetable ;see if there is a char to send
bra ponder3 ;loop back and do it again
** Which Menu Item was selected?
whichmenu:
clr.l d0 ;mycode shows which menu item was selected
move.w mycode,d0 ;mycode is word, not longword
** The next instructions masks mycode to isolate the six middle bits
** which contain the item number, and then compare it to item 1
and.w #%0000011111100000,d0 ;15-11=sub; 10-5=item; 4-0=menu
cmp.w #%0000000000000000,d0 ;0 is the 1st item #
beq itemnr1 ;the 1st menu item was picked
cmp.w #%0000000000100000,d0 ;1 is the 2nd item #
beq itemnr2 ;the 2nd menu item was picked
cmp.w #%0000000001000000,d0 ;10 is the 3rd item #
beq itemnr3 ;the 3rd item was picked
cmp.w #%0000000001100000,d0 ;11 is the 4th item#
beq itemnr4 ;toggle the letter only switch
jsr erase ;erase rectangle bounded by above
move.l #playmouse,IntuMsg ;if not either of the above
move.w #280,offsetleft ;print the message play with
move.w #5,offsettop ;your mouse
jsr printthis ;prints string pointed to by IntuMsg
bra ponder5 ;loop back to the beginning
itemnr1: ;send faster
jsr erase
move.l #pickitem1,IntuMsg ;first item picked so
move.w #270,offsetleft ;print the message on the screen
move.w #5,offsettop
jsr printthis
jsr meitem1 ;send faster
bra chgspeed ;thence to ponder5
itemnr2: ;send slower
jsr erase
move.l #pickitem2,IntuMsg ;second item picked so
move.w #270,offsetleft
move.w #5,offsettop
jsr printthis
jsr meitem2 ;send slower
bra chgspeed ;thence to ponder5
itemnr3: ;switch random
jsr erase
jsr clear
move.l #pickitem3,IntuMsg ;third item picked
move.w #270,offsetleft
move.w #5,offsettop
jsr printthis
jsr meitem3 ;switch random on/off
bra ponder5 ;use the same exit point
itemnr4:
jsr erase
move.l #pickitem4,IntuMsg ;Letter only Toggle Switch
move.w #270,offsetleft
move.w #5,offsettop
jsr printthis
jsr meitem4
bra ponder5
** Random Number Generator **
random:
clr.l d4
jsr GETRANDOM ;a random byte number in d0
and.l #$7f,d0 ;want only letters
cmp.l #43,d0 ;elim less than comma {,}
ble random ;go get another
cmp.l #123,d0 ;letter z
bge random
cmp.l #97,d0 ;letter a or better
bge 1$
tst.l letterflag ;if not 0 then only letters
bne random
cmp.l #58,d0 ;number 9
bge random
1$ cmp.l lastrandom,d0
beq random ;if they are the same dont use it
jsr aspace ;see if time for a space
move.l d0,-(sp)
lea onecharbuf,a0
move.l a0,d4
move.b d0,(a0)
jsr conwrite ;write it out
move.l (sp)+,d0 ;get the character back
move.l d0,lastrandom ;store for comparison
rts
GETRANDOM:
JSR onerandom ;make a random number
moveq #0,d0 ;clear d0 long
MOVE.B CELL1,D0 ;get the random # always in cell1
RTS ;to from whence it came
** GENERATE RANDOM #'S FROM TRANSACTOR, MAY, 1987
** MUST INITIALIZE WITH 21 RANDOM bytes
onerandom:
moveq #0,d0
moveq #0,d1
moveq #0,d2
move.b CELL21,D0
add.b CELL2,D0
move.b d0,TMP
movea.l #CBASE+21,a0
movea.l #CBASE+22,a1
move.l #19,D1
1$ move.b -(A0),-(a1) ;d2
dbra d1,1$
move.b TMP,CELL1 ;this is the random digit
rts
aspace:
move.l ranword,d5 ;what's in ranword
tst.l d5 ;if zero, then reseed
beq 1$
sub.l #1,ranword ;if not, reduce and return
2$ rts
1$ jsr GETRANDOM ;reseed the ranword
and.l #$07,d0
or.l #$01,d0
move.l d0,ranword
move.l #32,d0 ;put a space in the character generator
bra 2$
* CLEAR THE SCREEN**
clear:
move.l #clrscreen,d4 ;ascii 12,13,10,13,10,0
jsr conwrite
rts
setmessage:
movea.l MyWindow,a0 ;pointer to my window
movea.l wd_UserPort(a0),a0 ;pointer to our window's userport
move.l a0,userport ;save it
rts
getmessage:
clr.l d4 ;need this for junk
movea.l userport,a0 ;get userport pointer for call to GetMsg
movea.l AbsExecBase,a6 ;GetMsg is exec.lib, not intuition.lib
jsr _LVOGetMsg(a6)
tst.l d0 ;returns null if no message
beq 1$ ;escape if null
move.l d0,idcmpmessage ;pointer to this message structure needed
movea.l idcmpmessage,a1 ;for address indirect with displacement
move.l im_Class(a1),myclass ;which ICDMP flag ie., MENUPICK
move.w im_Code(a1),mycode ;word-which menu item # 0,1,etc.
movea.l AbsExecBase,a6 ;is pointed to by idcmpmessage, so that
jsr _LVOReplyMsg(a6) ;messages don't pile up
move.l idcmpmessage,d0 ;if d0 not 0 then return with message
1$ rts
** Intuition Message
welcomssg:
move.w #10,offsettop
move.w #50,offsetleft
move.l #line1,IntuMsg ;get pointer for first line to be
bsr lineprint ;printed
move.l #line2,IntuMsg ;second line
bsr lineprint
move.l #line3,IntuMsg
bsr lineprint
move.l #line4,IntuMsg
bsr lineprint
move.l #line5,IntuMsg
bsr lineprint
move.l #line6,IntuMsg
bsr lineprint
move.l #line7,IntuMsg
bsr lineprint
rts
lineprint add.w #20,offsettop
jsr printthis
rts
** the following will print what is in "IntuMsg"
printthis:
movea.l #0,a0 ;clear these else doesn't work
movea.l #0,a1
clr.l d0
clr.l d1
movea.l myrport,a0 ;pointer to rastport struct
movea.l #intuitext,a1 ;pointer to intuitext struct
move.w offsetleft,d0 ;leftedge offset
move.w offsettop,d1 ;top edge offset
movea.l IntuitionLibrary,a6 ;set library pointer
jsr _LVOPrintIText(a6) ;call print
rts
** Pause routine expects delay value in d0, with constant 10000
pause:
move.l #10000,d1
move.l d0,d2 ;put outter loop value in d2
pause1 move.l d1,d3 ;inner loop value in d3
pause2 nop
dbra d3,pause2 ;decrease inner loop till minus 1
dbra d2,pause1 ;same for outter loop
rts ;all done
** ERASE Part of Screen Routine - Fills a rectangle with the **
** background color. The rectangle is bounded by the starting
** and ending x,y coordinates (top left & bottom right)
** Start x pos in d0, end x pos in d1, both y pos' in d2
** Start at the bottom of the rectangleand draw lines in
** the background color up to the top of the screen
erase:
move.w #00,d0 ;now always erases the top 15 lines of screen
move.w #612,d1
move.w #15,d2
move.w d0,stx ;starting x position
move.w d1,endx ;ending x position
move.w d2,sty ;starting y position
move.w d2,endy ;ending y position
grids1 jsr drawline ;draw one horizontal line a pixel high
subi.w #1,sty ;reduce y position
subi.w #1,endy ;reduce y position
dbra d2,grids1 ;go back and draw another line
rts
** call this subroutine to draw a single line from coordinates
** stx,sty to endx,endy - initialize those values before calling
** the subroutine by move.w #nn,stx etc
drawline:
movea.l myrport,a0 ;pointer to our rastport
movea.l #oneline,a1 ;pointer to border structure
move.l #0,d0 ;offsets-left & top
move.l #0,d1
move.l IntuitionLibrary,a6
jsr _LVODrawBorder(a6)
rts
*** Exit program -- Close all open whatevers ***
close1:
jsr clear ;clr the screen
lea.l bestdx,a5
jsr sendmorse
close10:
movea.l ioreqptr,a1
movea.l AbsExecBase,a6
jsr _LVOCloseDevice(a6)
cl9_timerdevice movea.l timeIOTVptr,a1 ;ptr to IOTV structure
movea.l AbsExecBase,a6
jsr _LVOCloseDevice(a6)
close8_IOTV
move.l #IOTV_SIZE,d0 ;release timer IO Timerequest Structure
movea.l timeIOTVptr,a1
movea.l AbsExecBase,a6
jsr _LVOFreeMem(a6)
close7_remport movea.l timerportptr,a1 ;this closes both the port and
movea.l AbsExecBase,a6 ;the MP_SIZE memory since the addport does not
jsr _LVORemPort(a6) ;have a close of its own
move.l #MP_SIZE,d0 ;release the timer message port
movea.l timerportptr,a1
movea.l AbsExecBase,a6
jsr _LVOFreeMem(a6)
close6_MP move.l MP_Signalbit,d0 ;free the signal bit
movea.l AbsExecBase,a6
jsr _LVOFreeSignal(a6)
close5_sigbit move.l #sizeaudio,d0 ;this releases back to main memory the
movea.l audioblock,a1 ;three blocks of memory that I allocated
movea.l AbsExecBase,a6 ;for the speed prop gadget image, the
jsr _LVOFreeMem(a6) ;pitch prop gadget image and the audio
close4_audio move.l #pitchbytes,d0 ;wave form
movea.l pitchblock,a1
jsr _LVOFreeMem(a6)
close3_pitch move.l #imagebytes,d0
movea.l memblock,a1
jsr _LVOFreeMem(a6)
move.w #200,offsetleft ;position a goodbye message
move.w #50,offsettop
move.l #goodbye,IntuMsg
jsr printthis
move.l #50,d0
jsr pause
close2_image movea.l MyWindow,a0 ;clear the menu strip to
movea.l IntuitionLibrary,a6 ;avoid conflicts when the
jsr _LVOClearMenuStrip(a6) ;program is ended
movea.l MyWindow,a0
movea.l IntuitionLibrary,a6
jsr _LVOCloseWindow(a6) ;now close the window
Abort:
clr.l d0
rts ;all done, program has ended
** The Code Table
** code element to be sent is in d0
codetable:
jsr getcodechar ;get the next char fm keybuf
cmpi.b #0,d0
beq codet3 ;leave if char zero
jsr seedrandom
sendone cmpi.b #32,d0 ;is it a space? if so, skip code
beq endword
movea.l #alphacode,a0 ;get table pointer
clr.l d1 ;clr counter
move.b (a0),d1 ;set count at # of chars in table
adda.l #1,a0 ;move up to beginning of table
codet1 cmp.b 0(a0,d1),d0 ;index into table d1 bytes & compare
beq codet2 ;char found
dbra d1,codet1 ;decrement counter & try again
bra codet3 ;exit-no match found
codet2 move.b d1,ltrcode ;save the letter code number
jmp findltr ;get the letter
codet4:
bne codet3
move.l d0,-(sp) ;save char
move.l #linelen,carreturn
move.l (sp)+,d0 ;restore char
codet3 rts ;to keytest and start again
endword:
clr.l d0
move.b wordspce,d0 ;set up dbra loop
endword1 jsr dotpause ;element ;basic element spacing
dbra d0,endword1
jmp codet4 ;go update the line counter
findltr move.b ltrcode,d0 ;get the number back
add.b d0,d0 ;double it
movea.l #dotdash,a0 ;get table base
move.b 0(a0,d0),d1 ;the length of the code elements
subq.b #1,d1 ;dec by one for dbra ending in -1
addq.b #1,d0 ;up addr to code description
move.b 0(a0,d0),d2 ;get the morse letter
nextelm btst d1,d2 ;if bit 1 then dash
bne.s dash
dot jsr sndon ;turn on the sound
jsr dotpause ;element ;sound one dot element
elmstart jsr sndoff ;turn sound off
jsr dotpause ;noelement ;char space
elmdone dbra d1,nextelm ;if not -1 then get next element
endchar clr.l d1
move.b charspce,d1 ;do the character space-3 elms
endchar1 jsr dotpause ;element ;make space rem to make charspce one
dbra d1,endchar1 ;less than desired spaceing.
jmp codet4 ;all done-get next character
dash jsr sndon
jsr dashpause ;element ;this is longer by the weighting ratio
jmp elmstart ;the dash is done
*** KeyBuffer Maintainence routine. Does not alter d0 ***
addkeyst:
add.l #1,kbptr
add.l #1,kbcntr ;increment the keyboard counter
move.l kbendptr,d4 ;set up a compare
cmp.l kbptr,d4 ;is ptr less?
bgt 1$ ;d4 is > kbptr so branch
move.l #keybuf,kbptr ;reset to the beginnng
1$ rts
** This gets a char and increments codeptr
getcodechar:
clr.l d1
clr.l d0
move.l randflag,d1
tst.l d1 ;if zero, then fetch code from random routine
beq random ;this will send random code until menu changed
move.l codecntr,d1 ;see that code does not get ahead of keyboard
cmp.l kbcntr,d1 ;is d0 bigger, then dont send anything
bge 1$ ;just return until keyboard catches up
clr.l d0
movea.l codeptr,a0 ;set up indirect to get char to send
move.b (a0),d0 ;get the char
add.l #1,codeptr ;increment before testing
add.l #1,codecntr ;increment the code counter
move.l kbendptr,d4 ;are we at the end of the buffer
move.l codeptr,d5
cmp.l d5,d4
bgt 1$ ;branch if d4 > codeptr
move.l #keybuf,codeptr ;reset to the beginning
1$ rts ;returns with char in d0, & pointer incremented
** Chage Speed With Proportional Gadget **
chgspeed:
clr.l d0 ;cuz we're going from word to long
clr.l d1
moveq.l #0,d2
lea.l prop1,a0 ;get the prop struct base ptr
move.w pi_VertPot(a0),d0 ;must be word length
move.l factor,d1
mulu.w d1,d0 ;this should max at 983040 microseconds
move.l d0,micros
move.l #0,secs ;keep this at zero
move.l d0,d1 ;triple this
add.l d0,d1
add.l d0,d1 ;now triple & perhaps over 1 meg
lsr.l #1,d0 ;add 1/2 to make dash stretch a bit
add.l d0,d1 ;now dash ratio is 3&1/2
1$ cmp.l #million,d1 ;is d1 over one million
bls 2$ ;LS is low or same
sub.l #million,d1
add.l #1,d2 ;increase dashsecs
bra 1$ ;go back and try again
2$ move.l d2,dashsecs
move.l d1,dashmicros
lea.l prop2,a0 ;get pitch prop struct base ptr
clr.l d0
move.w pi_HorizPot(a0),d0 ;frequency ;also word length
divu #40,d0 ;divide down by 40
move.w d0,frequency ;store the new frequency
jsr sound
;tell the screen that we did this
jsr erase
clr.l d0
move.w frequency,d0 ;check the pitch
jsr printhex ;convert it to hex
move.l #hexprint,IntuMsg ;print it
move.w #270,offsetleft
move.w #5,offsettop
jsr printthis
clr.l d0
move.l micros,d0 ;check the speed [dot unit]
jsr printhex ;convert and print it
move.l #hexprint,IntuMsg
move.w #550,offsetleft
move.w #5,offsettop
jsr printthis
move.l #pitchmssg,IntuMsg
move.w #190,offsetleft
jsr printthis
move.l #speedmssg,IntuMsg
move.w #470,offsetleft
jsr printthis
move.l factor,d0 ;check the speed [dot unit]
jsr printhex ;convert and print it
move.l #hexprint,IntuMsg
move.w #400,offsetleft
move.w #5,offsettop
jsr printthis
bra ponder5
** Independant Menu Picks **
** send faster
meitem1:
move.l factor,d0
subi.l #1,d0 ;decrease factor if one or more
move.l d0,factor
beq meitem2 ;unless we get to zero
rts
** send slower
meitem2:
addi.l #1,factor
move.l factor,d0 ;factor should not be greater than 14
cmp.l #14,d0 ;or the program goes too slow.
beq meitem1
rts
** switch random = 0 keyboard = 1
meitem3:
tst.l randflag ;what is current state?
beq.s 1$ ;its zero, so we want to make it one
move.l #0,randflag ;it was one, so make it zero
2$ rts
1$ move.l #1,randflag ;make it one
move.l codeptr,d4 ;reprint remaining keyboard buffer
jsr conwrite
bra 2$ ;exit at one place
meitem4:
tst.l letterflag
beq.s 1$ ;reverse switch
move.l #0,letterflag
2$ rts
1$ move.l #1,letterflag
bra 2$
sound: ;Hardware Reference Manual describes this stuff
movea.l audioblock,a2 ;Find address of waveform sample data
move.l a2,Aud0Lc ;set waveform location channel 0
move.l a2,Aud1Lc ;set waveform location channel 1
* Length = number of WORDS (not bytes) in waveform sample
move.w #16,Aud0Len ;Set sample length channel 0
move.w #16,Aud1Len ;set sample length channel 1
* volume can go up to 64
move.w #64,Aud0vol ;Set channel 0 volume at maximum
move.w #64,Aud1vol ;Set Channel 1 volume at maximum
move.w frequency,d0 ;bigger period higher sound
move.w d0,Aud0per ;reset channel 0 period
move.w d0,Aud1per ;set channel 1 period
rts
ChanneL0:
move.w #(Setclr+DMAen+Aud0en),DMAconw ;enable channel 0
move.l #30,d0
bsr pause
move.w #(OffDMA+Aud0en),DMAconw ;disable channel 0
ChanneL1:
move.w #(Setclr+DMAen+Aud1en),DMAconw ;enable channel 1
move.l #45,d0
jsr pause
move.w #(OffDMA+Aud1en),DMAconw ;disable channel 1
rts
sndon:
move.w #(Setclr+DMAen+Aud1en),DMAconw ;turn sound on
move.w #(Setclr+DMAen+Aud0en),DMAconw ;ch 0 & 1
rts
sndoff:
move.w #(OffDMA+Aud1en),DMAconw ;turn sound off
move.w #(OffDMA+Aud0en),DMAconw ;ch 0 & 1
rts
printhex:
;prints a 16-bit hex number using d0 and hexfield
clr.l d1 ;nibble holder
clr.l d2 ;downcounter
moveq #3,d2
lea.l hexfield,a0
lea.l hexlist,a1
bra 1$
2$ sub.l #1,d2
asr.l #4,d0 ;shift to next nibble
1$ move.l d0,d1 ;move it
andi.l #$0f,d1 ;what is the nibble
move.b 0(a1,d1.l),d1 ;get the ascii equivalent
move.b d1,0(a0,d2.l) ;put it in the hexfield
tst.l d2
beq 3$
bra 2$
3$ rts
seedrandom:
lea CBASE,a0 ;this subroutine seeds the random # generator
move.l basecounter,d1 ;when the user types in some letters to send
move.b d0,0(a0,d1.l) ;code.
sub.l #1,d1
bmi 2$
1$ rts
2$ move.l #19,basecounter
bra 1$
yestheend:
SECTION data,DATA
CBASE DC.B 19
CELL1 DC.B 24
CELL2 DC.B 37,42,55,68,73,86,91,100,112,128,134,146,159
DC.B 165,171,180,197,205,212
CELL21 DC.B 223
TMP DC.B 0,0,0,0
CNOP 0,4
TimerPortName dc.b 'timer',0
hexlist dc.b '0123456789abcdef',0
consolename dc.b 'console.device',0
timername dc.b 'timer.device',0
IntuitionName dc.b 'intuition.library',0
GraphicsName dc.b 'graphics.library',0
clrscreen dc.b 12,13,10,13,10,0
cnop 0,4 ;this is used to allign following stuff on a
** long word address. If not done disaster can strike
menuflags EQU MENUENABLED!MIDRAWN ;FROM INTUITION MENU STRUCTURE
itemflags EQU ITEMTEXT!ITEMENABLED!HIGHCOMP!COMMSEQ
item3flags EQU ITEMTEXT!ITEMENABLED!HIGHCOMP!CHECKIT!COMMSEQ!MENUTOGGLE
MyGadgets EQU WINDOWSIZING!WINDOWDRAG!WINDOWDEPTH!WINDOWCLOSE
MyFeatures EQU SMART_REFRESH!ACTIVATE!GIMMEZEROZERO ;!VANILLAKEY
MyFlags EQU MyGadgets!MyFeatures
gadgrel EQU GRELRIGHT!GRELHEIGHT ; !GRELBOTTOM
gadg1rel EQU GRELHEIGHT!GRELBOTTOM
gadgflags EQU GADGHIMAGE!GADGIMAGE
gadg1flags EQU GADGHIMAGE!GADGIMAGE
gadgtype EQU PROPGADGET!GZZGADGET
propflags EQU FREEVERT!KNOBHIT ;!FREEHORIZ !AUTOKNOB
prop1flags EQU KNOBHIT!FREEHORIZ ;!AUTOKNOB
menupick EQU MENUPICK
MyTitle: dc.b ' Morse Code Practice by NO2D',0 ;title of our window
iobuffer dc.b ' All windows, structures & devices have opened.',10,10,13,0
menutitle dc.b ' Morse Menu',0 ;null term string
fititle dc.b ' Send Faster',0 ;first item in menu
sititle dc.b ' Send Slower',0 ;second item in menu
tititle dc.b ' Send Random',0 ;third menu item
fotitle dc.b ' Letters Only',0 ;forth menu item
offsetleft dc.w 0
offsettop dc.w 0
frequency dc.w 420
cnop 0,4
** MENU and MENU ITEM STRUCTURES
mymenu:
dc.l 0 ;menu pointer
dc.w 0,0,200,100 ;leftedge,topedge,width,height
dc.w MIDRAWN!MENUENABLED ;menuflags MENUENABLED & MIDRAWN
dc.l menutitle ;pointer to title string
firstmenuitem dc.l 0 ;pointer to first menu item (menuitemone)
dc.w 0,0,0,0 ;for the jazz-beat (who knows what that means)
** The first menu item structure **
menuitemone dc.l 0 ;pointer to second menuitem
dc.w 0,0,180,11 ;left,top,width,height of select box
dc.w itemflags ;see flags set above
dc.l 0 ;mutual exclude null=no item excluded
itemonetext dc.l 0 ;pointer to intuitext struct for item text
dc.l 0 ;pointer to highlight alternate image/text
dc.b 70,0 ;set if COMMSEQ flag is set & a kluge byte 'f'
dc.l 0 ;subitem if any
dc.w 0 ;next selected item in drag 'mi_NextSelect'
** remember to initialize all of these things
firstitemtext:
dc.b 0,1,4,0 ;pens drawmode & kluge
dc.w 0,0 ;leftedge,topedge
dc.l 0 ;textfont null = default
fitext dc.l 0 ;textpointer
dc.l 0 ;pointer to next intuitext struct
** The second menu item structure **
menuitemtwo dc.l 0 ;pointer to third menuitem
dc.w 0,15,180,11 ;left,top,width,height of select box
dc.w itemflags ;see flags set above
dc.l 0 ;mutual exclude null=no item excluded
itemtwotext dc.l 0 ;aptr to intuitext struct for this item text
dc.l 0 ;aptr to highlight alternate image/text
dc.b 83,0 ;set if COMMSEQ flag is set & a kluge byte 's'
dc.l 0 ;subitem if any
dc.w 0 ;next selected item in drag 'mi_NextSelect'
** remember to initialize all of these things
seconditemtext:
dc.b 0,1,4,0 ;pens drawmode & kluge
dc.w 0,0 ;leftedge,topedge
dc.l 0 ;textfont null = default
sitext dc.l 0 ;textpointer
dc.l 0 ;pointer to next intuitext struct
cnop 0,4
** The forth menu item structure **
menuitem4 dc.l 0 ;pointer to second menuitem
dc.w 0,45,180,11 ;left,top,width,height of select box
dc.w item3flags ;see flags set above
dc.l 0 ;mutual exclude null=no item excluded
item4text dc.l 0 ;pointer to intuitext struct for item text
dc.l 0 ;pointer to highlight alternate image/text
dc.b 76,0 ;set only if COMMSEQ flag is set & a kluge byte
dc.l 0 ;subitem if any
dc.w 0 ;next selected item in drag 'mi_NextSelect'
** remember to initialize all of these things
forthitemtext:
dc.b 0,1,4,0 ;pens drawmode & kluge
dc.w 0,0 ;leftedge,topedge
dc.l 0 ;textfont null = default
fotext dc.l 0 ;textpointer
dc.l 0 ;pointer to next intuitext struct
cnop 0,4
** The third menu item structure **
menuitem3 dc.l 0 ;pointer to second menuitem
dc.w 0,30,180,11 ;left,top,width,height of select box
dc.w item3flags ;see flags set above
dc.l 0 ;mutual exclude null=no item excluded
item3text dc.l 0 ;pointer to intuitext struct for item text
dc.l 0 ;pointer to highlight alternate image/text
dc.b 65,0 ;set only if COMMSEQ flag is set & a kluge byte
dc.l 0 ;subitem if any
dc.w 0 ;next selected item in drag 'mi_NextSelect'
** remember to initialize all of these things
thirditemtext:
dc.b 0,1,4,0 ;pens drawmode & kluge
dc.w 12,0 ;leftedge,topedge
dc.l 0 ;textfont null = default
titext dc.l 0 ;textpointer
dc.l 0 ;pointer to next intuitext struct
** An IntuiText Structure. Use this to do the "printthis"
** routine, with pointer to message in IntuMsg
intuitext:
dc.b 1,1,2,0 ;FT & bk pen, drawmode, kluge
dc.w 0,0 ;leftedge topedge
dc.l 0 ;textfont normal if 0
IntuMsg dc.l 0 ;pointer to null terminated text to be printed
dc.l 0 ;next intuitext structure-null if none`
cnop 0,4
line1 dc.b 'Welcome to the Morse Code Practice Program.',0
line2 dc.b 'It is designed to help you improve your Morse Code',0
line3 dc.b 'sending and receiving speed, with the hope that it',0
line4 dc.b 'will encourage you to get your amatuer radio license',0
line5 dc.b 'or to upgrade. This is written in Assembly Language,',0
line6 dc.b 'and free distribution is encouraged.',0
line7 dc.b 'by Peter V. Inskeep, NO2D -- CIS 72017,1211.',0
pitchmssg dc.b 'Pitch =',0
speedmssg dc.b 'Speed =',0
bestdx dc.b 'best dx es 73 tu de no2d = \',0
goodbye dc.b 'GOOD BYE NOW! 73 de NO2D',0
pickgadget dc.b 'Gadget Picked',0
pickitem1 dc.b 'Send Faster',0
pickitem2 dc.b 'Send Slower',0
pickitem3 dc.b 'Switch Code Source',0
pickitem4 dc.b 'Letter Only Toggle Switch',0
playmouse dc.b 'Playing with your Mouse?',0
cnop 0,2
cqmssg dc.b 'cq cq cq de no2d no2d k',0
cnop 0,4
longnull dc.b 32,0,0,0,0
cnop 0,4
hexprint dc.b '$ '
hexfield dc.b 'fedc',0 ;five bytes, four used zero ends it
cnop 0,4
** A border structure to support the erase routine.
oneline:
dc.w 0,0 ;left & top offsets
dc.b 2,2 ;1,2 forground and background pens ;33333
dc.b 0 ;jam1 drawing modes
dc.b 2 ;number of xy coordinates to be drawn
oneline1 dc.l 0 ;where the coordinates are (onelinelist)
dc.l 0 ;next border structure-null if none
cnop 0,4
onelinelist:
stx dc.w 1 ;stuff these with the line starting and ending
sty dc.w 1 ;coordinates for each line you want to draw
endx dc.w 1 ;then call the border subroutine with the
endy dc.w 1 ;oneline border structure address
cnop 0,4
************** Gadget Rendering Section **************************;
image2:
dc.w 0,0,64,11,1
dc.l 0 ;image data pointer
dc.b 1,0
dc.l 0
cnop 0,4
image1:
dc.w 0 ;left
dc.w 0 ;top
dc.w 16 ;no. of pixels wide
dc.w 14 ;no. of rows high
dc.w 1 ;bitplane depth 1 or 2 for what I am doing use 1
im1addr dc.l 0 ;testimage
dc.b 1 ;PlanePick
dc.b 0 ;PlaneOnOff
dc.l 0 ;next image
prop2:
dc.w prop1flags
dc.w $3000 ;pi_HorizPot
dc.w $0
dc.w $600
dc.w $0
dc.w 20
dc.w 20
dc.w 500
dc.w 500
dc.w 0 ;g1left
dc.w 0 ;g1top
prop1:
dc.w propflags ;flags 00
dc.w 0 ;pi_HorizPot 02
dc.w $4000 ;pi_VertPot 04 ;code speed for propgadget
dc.w $0 ;pi_HorizBody the portion of the total that will 06
dc.w $300 ;pi_VertBody show in the gadget window 08
dc.w 20 ;pi_CWidth 0a
dc.w 20 ;pi_CHeight 0c
dc.w 500 ;pi_HPotRes 0e
dc.w 500 ;pi_VPotRes 10
dc.w gleft ;pi_LeftBorder 12
dc.w gtop ;pi_TopBorder 14
gadget2:
dc.l 0 ;ptr to next gadget in list
dc.w g1left ;left edge of gadget relative or absolute
dc.w g1top ;top edge of gadget relative or absolute
dc.w g1wide ;width of the gadget itself
dc.w g1high ;height of the gadget
dc.w gadg1flags!gadg1rel ;flags
dc.w RELVERIFY!BOTTOMBORDER ;!TOPBORDER ;activation
dc.w PROPGADGET!GZZGADGET ;gadget type (03) & ($2000)
dc.l image2 ;ptr- border, image, or none(0)
dc.l 0 ;select render alternate border, image
dc.l 0 ;g1itxt ;gadget text if any
dc.l 0 ;mutual exclude
dc.l prop2 ;special info for prop, string and interger gadgets
dc.w 1 ;user defined gadget id field
dc.l 0 ;pointer to user data
gadget1:
dc.l gadget2 ;ptr to next gadget in list
dc.w gleft ;left edge of gadget relative or absolute
dc.w gtop ;top edge of gadget relative or absolute
dc.w gwide ;width of the gadget itself
dc.w ghigh ;height of the gadget
dc.w gadgflags!gadgrel ;flags
dc.w RELVERIFY!RIGHTBORDER ;!TOPBORDER ;activation
dc.w PROPGADGET!GZZGADGET ;gadget type (03) & ($2000)
dc.l image1 ;ptr- border, image, or none(0)
dc.l 0 ;select render alternate border, image
dc.l 0 ;g1itxt ;gadget text if any
dc.l 0 ;mutual exclude
dc.l prop1 ;special info for prop, string and interger gadgets
dc.w 1 ;user defined gadget id field
dc.l 0 ;pointer to user data
** A NEW WINDOW STRUCTURE - GADGETUP ADDED 8/27/87 **
newwindow:
dc.w 0,0,640,200 ;Left,Top,Width,Height
dc.b 0,1 ;DetailPen, BlockPen
dc.l CLOSEWINDOW!MENUPICK!GADGETUP ;!FOLLOWMOUSE;IDCMFlags
dc.l MyFlags ;Flags-described above
dc.l gadget1 ;gadget pointer load yours here
dc.l 0 ;CheckMark Default
dc.l MyTitle ;Title-see above
dc.l 0 ;Screen: 0=Default
dc.l 0 ;BitMap Default
dc.w 50,150,640,200 ;Minwidth,height;Maxwidth,height
dc.w WBENCHSCREEN ;Type- customscreen is more work
cnop 0,4
onecharbuf dc.b 0,0,0,0,0,0,0,0 ;buffer for onechar (onecharptr)
cnop 0,4
timertest dc.b 'Timer.device open and 3 sec delay executed',13,13,10,0
testmsg dc.b ' MORSE CODE TEST PROGRAM Ver. 1.1',13,10
dc.b ' by Peter Inskeep - NO2D',13,10
dc.b ' Original dated January 10, 1987',13,10,13,10
dc.b ' Type lower case characters on the keyboard. Each',13,10
dc.b ' character should print on the screen and its morse',13,10
dc.b ' code will sound through both speakers.',13,10,10
dc.b ' Use the Prop Gadgets at the right edge and the bottom of',13,10
dc.b ' the window to change sending speed and pitch.',13,10,10
dc.b ' Or, use the Menu to send faster or slower,',13,10
dc.b ' or to switch between keyboard and random sending.',13,10
dc.b ' Choose to send random letters, or also numbers and',13,10
dc.b ' punctuation.',13,10,10
dc.b ' Learn morse code and become a Ham Radio Operator.',13,10,0
endline dc.b 13,10,10,0
testbuff dc.b '0',13,10,0
** Timing counters for dot and dash sound elements
basecounter dc.l 19
charspce dc.b 2
wordspce dc.b 7
prtachar dc.b 0,0,0,0
cnop 0,4
alphacode:
dc.b 43 ;44 chars in table [0-43]
dc.b '?.,-/=\;' ;8 char ;=(._._.) \(..._._) ;(_..._)
dc.b '0987654321' ;10 char
dc.b 'jqyzxcpbvflowgdkurhsmnaite',0 ;26 char
dotdash:
dc.b 6,%00001100 ; ?
dc.b 6,%00010101 ; .
dc.b 6,%00110011 ; ,
dc.b 5,%00010001 ; -
dc.b 5,%00010010 ; /
dc.b 5,%00001010 ; = .-.-.
dc.b 6,%00000101 ; \ ...-.-
dc.b 5,%00010001 ; ; -...-
dc.b 5,%00011111 ; 0
dc.b 5,%00011110 ; 9
dc.b 5,%00011100 ; 8
dc.b 5,%00011000 ; 7
dc.b 5,%00010000 ; 6
dc.b 5,%00000000 ; 5
dc.b 5,%00000001 ; 4
dc.b 5,%00000011 ; 3
dc.b 5,%00000111 ; 2
dc.b 5,%00001111 ; 1
dc.b 4,%00000111 ; j
dc.b 4,%00001101 ; q
dc.b 4,%00001011 ; y
dc.b 4,%00001100 ; z
dc.b 4,%00001001 ; x
dc.b 4,%00001010 ; c
dc.b 4,%00000110 ; p
dc.b 4,%00001000 ; b
dc.b 4,%00000001 ; v
dc.b 4,%00000010 ; f
dc.b 4,%00000100 ; l
dc.b 3,%00000111 ; o
dc.b 3,%00000011 ; w
dc.b 3,%00000110 ; g
dc.b 3,%00000100 ; d
dc.b 3,%00000101 ; k
dc.b 3,%00000001 ; u
dc.b 3,%00000010 ; r
dc.b 4,%00000000 ; h
dc.b 3,%00000000 ; s
dc.b 2,%00000011 ; m
dc.b 2,%00000010 ; n
dc.b 2,%00000001 ; a
dc.b 2,%00000000 ; i
dc.b 1,%00000001 ; t
dc.b 1,%00000000 ; e
cnop 0,4
SECTION IMAGEDATA,DATA
beginpubmem:
theimage:
dc.w %1111111111111111
dc.w %1100000000000011
dc.w %1100000000000011
dc.w %1100011111100011
dc.w %1100110000110011
dc.w %1100110000000011
dc.w %1100001111000011
dc.w %1100000000110011
dc.w %1100000000110011
dc.w %1100110000110011
dc.w %1100011111100011
dc.w %1100000000000011
dc.w %1100000000000011
dc.w %1111111111111111
imagebytes equ *-beginpubmem
pitchimage:
dc.w %1111111111111111,%1111111111111111,%1111111111111111,%1111111111111111
dc.w %1100000000000000,%0000000000000000,%0000000000000000,%0000000000000011
dc.w %1100111110000111,%1111100001111111,%1110000001111000,%0001100000110011
dc.w %1100110001100000,%1100000001000110,%0010000011000110,%0001100000110011
dc.w %1100110001100000,%1100000000000110,%0000000110000000,%0001100000110011
dc.w %1100111110000000,%1100000000000110,%0000000110000000,%0001111111110011
dc.w %1100110000000000,%1100000000000110,%0000000110000000,%0001100000110011
dc.w %1100110000000000,%1100000000000110,%0000000011000110,%0001100000110011
dc.w %1100110000000111,%1111100000000110,%0000000001111000,%0001100000110011
dc.w %1100000000000000,%0000000000000000,%0000000000000000,%0000000000000011
dc.w %1111111111111111,%1111111111111111,%1111111111111111,%1111111111111111
pitchbytes equ *-pitchimage
dcb.w 50,1
sizepubmem equ *-beginpubmem
cnop 0,4
beginaudio:
Wavesample:
dc.b 0,32,64,96,120,120,120,120,120,120,120,120
dc.b 90,64,32,0,-32,-64,-90,-120,-120,-120
dc.b -120,-120,-120,-120,-120,-120,-96,-64,-32,0
sizeaudio equ *-beginaudio
SECTION mem,BSS
IntuitionLibrary ds.l 1 ;keep address of Intuition here
GraphicsLibrary ds.l 1 ;keep address of Graphics here
readbufptr ds.l 1 ;for conread a 0 term string
readbuffer ds.l 100 ;storage for readbufptr
onecharptr ds.l 1 ;pointer for one character write buffer
bufptr ds.l 1 ;a general buffer pointer
buffer ds.l 20 ;a one screen line buffer
;handle ds.l 1 ;console file read handle
prtbuff ds.l 25 ;buffer for special print (end in 0)
prtptr ds.l 1 :pointer for the spec.print buffer
codecntr ds.l 1 ;counter for code sending
kbcntr ds.l 1 ;counter for keyboard usage (with codecntr)
ltrcode ds.l 1 ;store letter number here
carreturn ds.l 1 ;holds carriage return in linelen
MyWindow ds.l 1 ;address of the structure describing our window
mywdsize ds.l 1 ;size of the window
bucket ds.l 1 ;a place to dump things
userport ds.l 1 ;pointer to wd_UserPort structure
myclass ds.l 1 ;ICDMP Class or equal to flag ie., MENUPICK
menupoint ds.l 1 ;pointer to menu structure
idcmpmessage ds.l 1 ;the message class reported by intuimessage
myrport ds.l 1 ;this windows rastport
secs ds.l 1 ;seconds in IntuiMessage
micros ds.l 1 ;microseconds in IntuiMessage
dashsecs ds.l 1 ;for the dash seconds
dashmicros ds.l 1 ;for the dash micros
keybuf ds.l bufferlen ;keystroke buffer
kbptr ds.l 1 ;keybuf current position pointer
kbendptr ds.l 1 ;end of keybuf pointer
codeptr ds.l 1 ;code sending current position (not same as kbptr)
randflag ds.l 1 ;random flag 1=keyboard 0=random
consoleflag ds.l 1 ;flag for success opening console 0=success
timerflag ds.l 1 ;same for timer
letterflag ds.l 1 ;letter only flag switch
timerbase ds.l 1 ;see pg b3, Rom Kernal Manual
ioreadbuffer ds.l 20 ;read buffer 80 characters max
iowritbuf ds.l 1 ;one char write buffer, but longword
ioreadbuf ds.l 1 ;one char read buffer, but longword
ioreqptr ds.l 1 ;pointer to io request block
ranword ds.l 1 ;a cntr for random word space
memblock ds.l 1 ;pointer to image data in memory
pitchblock ds.l 1 ;ptr to pitch image data
audioblock ds.l 1 ;ptr to audio data block
lastrandom ds.l 1 ;store the last random # here
counter ds.l 1 ;a general counter
timerportptr ds.l 1 ;pointer to chip reply messageport structure
timeIOTVptr ds.l 1 ;a pointer to timerequest structure IOTV_
MP_Signalbit ds.l 1 ;signal bit for the timerportptr
factor ds.l 1 ;times factor for speed
mousex ds.w 1 ;x mouse coordinate
mousey ds.w 1 ;y mouse coordinate
mycode ds.w 1 ;for things line menu# ie, 0,1,2,3, etc.
infrequency ds.w 1 ;holds sound frequency fm horizpot
END